package com.zhoujian.creational;

import java.io.Serializable;

/**
 * 双重检查锁的实现
 * @author 周健
 * @creatTime 2023-09-04
 */

public class DoublecheckSingleton implements Serializable {
    //创建对象，不是一个原子性操作，即使使用了双重检查锁，也可能在创建的过程中产生半初始化状态
    //为了实现原子性操作，需要使用关键字volatile
    //volatile作用：1.保证内存可见 2.保证有序性
    private static volatile DoublecheckSingleton instance;

    private DoublecheckSingleton() {
        //升级版本---》为了不让人通过反射来破坏单例
        if(instance != null){
            throw new RuntimeException("该对象是单例的，无法创建多个");
        }
    }

    //第一次创建需要双锁，一旦创建好了，就不在需要上锁
    //事实上，获取单例并没有线程安全的问题
    public static DoublecheckSingleton getInstance() {
        if (null == instance){//当有大量的线程进入时，先判断是否为空
            synchronized (DoublecheckSingleton.class){
                if (null == instance) {//一旦进入二次判断，就会按序排列
                    instance = new DoublecheckSingleton();
                }
            }
        }
        return instance;
    }
    public Object readResolve(){//使用readResolve方法，保证序列化的时候只有一个实例对象
        return instance;
    }
}